#ifndef _OTA_H_
#define _OTA_H_


#include "bsp_uart.h"
#include "AT24CXX.h"
#include "key.h"
#include "Timer.h"
#include "flash.h"

#include "cJSON.h"
#include "base64.h"
#include "check.h"

#include <stdlib.h>
#include <stdbool.h>


//#define     USE_4G_MODELS                     1
//#define     USE_ESP32_C3                      1
#define     USE_OTA_SOFT_WARE                   1

#define     FLASH_BaseAddr                      0x0800D000
#define     APP_ADDR                            0xD000


#define     DMA_RX_BUFFER_SIZE                  1024
#define     DMA_TX_BUFFER_SIZE                  1024


#define     FactoryInformationMaxSize           100
#define     FactoryInformationBaseAddr          0

#define     UpgradeRequestInformationAddr       101
#define     UpgradeRequestInformationMaxSize    50
#define     UpgradeNeed                         0x01
#define     UpgradeNotNeed                      0x02

#define     cJSON_Parse_failed              0x01
#define     cJSON_GetObjectItem_failde      0x02
#define     App_Exists                      0x03
#define     App_Not_Exists                  0x04

#define     TransEndSeq                     99999999
#define     MaxWaitTime                     5       // s


extern volatile char uart2_dma_rx_buffer[DMA_RX_BUFFER_SIZE];
extern volatile char uart2_dma_tx_buffer[DMA_TX_BUFFER_SIZE];

extern volatile uint8_t  OTA_END_FLAG;
extern size_t FactoryInformationSize;
extern volatile char device_id[10];

typedef struct {
    char*       device_id;
    char*       current_fw;
    uint32_t    fw_size;
} FactoryInformationTypedef;

extern volatile FactoryInformationTypedef FactoryInformation;

typedef struct {
    char*            device_id;
    char*            status;
    uint32_t         next_seq;
    bool             end_flag;
} DeviceAckTypedef;
extern volatile DeviceAckTypedef ACK;

typedef struct {
    uint32_t         current_blocks;
    uint32_t         offset;
    char*            base64_data;
    char*            check_code;
    uint8_t          bin_data;
    uint32_t         remaining_blocks;
    uint32_t         next_seq;
} DataReceptionTypedef;
extern volatile DataReceptionTypedef Data_Reception_param;

typedef struct {
    const char*   server_addr;
    int           port;
    const char*   pubtopic;
    const char*   subtopic;
    const char*   client_id;
    const char*   user_name;
    const char*   password;
    int           qos;
} ML307R_MQTT_Config_Typedef;

extern volatile u8 IS_Updating;

void OTA_Init(void);
void UpgradeRequestInformationToNo(void);
void UpgradeRequestInformationToYes(void);
uint8_t Upgrade_Request_Need_Detect(void);
void Send_UpgradeRequest(void);
uint8_t AppExists(void);


#endif
